package generator.denpendency.detection;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;

public class LinearProgramming {

	private double[][] nd;
	private int fileNum;
	private int topicNumbers;
	public static PrintWriter pwTemp;
	private int lpDimension;
	
	Runtime rt = Runtime.getRuntime();
	public LinearProgramming(double[][] theta, int fileNum, int topicNumbers, String lpTemp, int lpDimension) throws IOException {
		this.nd = theta;
		this.fileNum = fileNum;
		this.topicNumbers = topicNumbers;
		pwTemp = new PrintWriter(new FileWriter(lpTemp));
		this.lpDimension = lpDimension;
	}
	
	public ArrayList<ArrayList<Double>> getAlphaNormalize() {

		System.out.println("getAlphaNormalize()");
		
		ArrayList<ArrayList<Double>> weightList = new ArrayList<ArrayList<Double>>();
		
		//compute alpha vector
		double[] weight = null;
		
		int dimension = lpDimension;
		
		for(int i = 0; i < topicNumbers; i++) {
			
			pwTemp.println("key: " + i);
			
			weight = LP(i, dimension); 
			
			ArrayList<Double> al = new ArrayList<Double>();
			for(int w = 0; w < weight.length; w++)
				al.add(weight[w]);
			
			weightList.add(al);
		}
		System.out.println("Lp: Used Memory = " + (rt.totalMemory() - rt.freeMemory()));
		
		return weightList;
		
	}	
	
	   /**
		 * 閿熸枻鎷烽敓鐨嗚锟�
		 * @param key
		 * @param dimension
		 * @return weight
		 */
		
		private double[] LP(int topic, int dimension) {
			
			Matrix matrixCompute = new Matrix();
			
			int i = 0;
			int j = 0;
			int k = 0;
			//System.out.println(fileNum + " " + dimension);
			int rows = fileNum - dimension;
			int columns = dimension + 1;
			
			double[] weight = new double[columns];
			
			double[][] matrix = new double[rows][columns];
			double[][] matrixTransposition = new double[columns][rows];
			double[][] matrixInverse = new double[columns][columns];
			
			double[] result = new double[rows];
			
			//int numbers = 2 * dimension - 1;
			double[] frequencies = new double[fileNum];
			for(i = 0; i < fileNum; i++)
				frequencies[i] = nd[i][topic];
			
			pwTemp.println("frequencies: ");
			matrixCompute.display(frequencies, frequencies.length);
			
			//---------HERE--------------
			int start = dimension;
			int end = fileNum;
				
			int flag0 = 0;
			for(i = 0 ; start < end; start++, i++) {
				result[i] = frequencies[start];
				if(result[i] == 0) flag0++;
			}
			
			if(flag0 >= result.length / 3) return weight;

			pwTemp.println("result: ");
			matrixCompute.display(result, result.length);
			
			for(j = 0; j < rows; j++) {
				
				matrix[j][0] = 1; 
				matrixTransposition[0][j] = 1;
			}
			
			for(i = 0; i < rows; i++) {
				
				for(j = 1, k = i; j < columns; j++, k++) {
								
					matrix[i][j] = frequencies[k];
					matrixTransposition[j][i] = frequencies[k];
					
				}
			}
			
			pwTemp.println("matrix: ");
				
			matrixCompute.display(matrix, rows, columns);
			
			pwTemp.println("matrixTransposition: ");
			matrixCompute.display(matrixTransposition, columns, rows);
			
			//閿熸枻鎷烽敓鏂ゆ嫹
			matrixInverse = matrixCompute.multiple(matrixTransposition, matrix, columns, rows, columns);
			
			matrixCompute.display(matrixInverse, columns, columns);
			matrixInverse = matrixCompute.inverse(matrixInverse, columns);
		
			pwTemp.println("matrixInverse: ");
			matrixCompute.display(matrixInverse, columns, columns);
			
			double[] XTY = new double[columns];
			XTY = matrixCompute.multiple(matrixTransposition, result, columns, rows);
			
			pwTemp.println("XTY: ");
			matrixCompute.display(XTY, XTY.length);
			
			//matrixInverse * XTY
			weight = matrixCompute.multiple(matrixInverse, XTY, columns, columns);
			
			
			return weight;
		}	
	
}
